<script setup lang="ts">
import type { CollapseModelValue, TransferKey } from 'element-plus';

import type { Ref } from 'vue';

import type { EChartsCoreOption } from '#/hooks';

import {
  computed,
  inject,
  onBeforeUnmount,
  onMounted,
  reactive,
  ref,
  watch,
} from 'vue';

import { ElDArrowLeft, ElHide, ElInfoFilled, ElView } from '@vben/icons';

import {
  ElCol,
  ElCollapse,
  ElCollapseItem,
  ElIcon,
  ElInput,
  ElInputNumber,
  ElMessage,
  ElOption,
  ElPopover,
  ElRadio,
  ElRadioGroup,
  ElRow,
  ElSelect,
  ElSlider,
  ElSwitch,
  ElTooltip,
  ElTransfer,
} from 'element-plus';

import { vectorServiceApi } from '#/api';
import { barTootipCallback } from '#/assets/style';
import { ChartRender } from '#/assets/visualization-template';
import { Echarts as BarChart } from '#/components/echarts';
import { usePublicStore, useSceneStore } from '#/store';
import { getRampUrl } from '#/utils';

interface barChartSeriesData {
  name: string;
  type: string;
  barWidth: number;
  label: object;
  itemStyle?: { color: Function | string };
  barGap?: string;
}
interface Option {
  key: number;
  label: string;
  // disabled: boolean
}
const sceneStore = useSceneStore();
const publicStore = usePublicStore();
const chartRender = new ChartRender(); // 调用渲染方法
const currentLayer = inject('currentSelectedLayer') as any;
const isDragging: Ref<Boolean> = inject('isDragging', ref(false));
const activeNames = ref(['chartParams']);
const backgroundColor = ref('#F0E6B2');
const opacity = ref(100);
const fieldList = ref<Option[]>([]); // 当前图层的字段列表
const colorRamp = ref('echarts_light');
const selectedFieldsIndex = ref<number[]>([]);
const isPreView = ref(false);
const currentSource = ref();
const chartWidth = ref(150);
const chartHeight = ref(150);
const barHeight = ref(80);
const barWidth = ref(18);
const isLabelOpen = ref(true);
const labelSize = ref(10);
const feature = ref({} as any);
const colorsList = ref<string[]>([]); // 存储柱体颜色的数组
const chartSeriesData = ref<barChartSeriesData[]>([]);
const chartData = ref<(number | string)[]>(['value']);
const chartOptions: Ref<EChartsCoreOption> = ref({
  tooltip: {
    // show: false,
    trigger: 'item',
    formatter: barTootipCallback(currentLayer.value.name),
  },
  dataset: {
    // source: [['value',43.3, 85.8, 93.7]]
    source: computed(() => {
      const array: any[] = [];
      array.push(chartData.value);
      return array;
    }),
  },
  grid: {
    // 距离容器底部的距离
    bottom: computed(() => `${(100 - barHeight.value) / 2}%`),
    top: computed(() => `${(100 - barHeight.value) / 2}%`),
  },
  xAxis: {
    type: 'category',
    show: false,
  },
  yAxis: {
    show: false,
  },
  series: chartSeriesData,
  // series: [
  //   {
  //     name: currentLayer.value.name,
  //     type: 'pie',
  //     radius: computed(() => `${chartSize.value}%`),
  //     label: {
  //       show: isLabelOpen,
  //       formatter: '{c}',
  //       position: 'inside',
  //       fontSize: labelSize
  //     },
  //     labelLine: {
  //       show: false
  //     },
  //     data: chartData,
  //     itemStyle: {
  //       opacity: 100  // 设置透明度为0，即完全透明(控制显隐)
  //     },
  //     emphasis: {
  //       itemStyle: {
  //         shadowBlur: 3,
  //         shadowOffsetX: 0,
  //         shadowColor: 'rgba(0, 0, 0, 0.5)'
  //       }
  //     }
  //   }
  // ]
});

const barChartRenderParams = reactive({
  layer: currentLayer.value,
  selectedFields: computed(() => {
    return selectedFieldsIndex.value.map(
      (index) => fieldList.value[index - 1]?.label,
    );
  }),
  colorRamp,
  background: {
    point: {
      layout: {
        visibility: 'visible',
      },
      paint: {
        'circle-color': backgroundColor,
        'circle-opacity': computed(() => opacity.value / 100),
        'circle-radius': 10,
      },
    },
    polygon: {
      layout: {
        visibility: 'visible',
      },
      paint: {
        'fill-color': backgroundColor,
        'fill-opacity': computed(() => opacity.value / 100),
        'fill-outline-color': '#000000',
      },
    },
  },
  markerOptions: {
    chartWidth,
    chartHeight,
  },
  chartOptions,
  seriesOptions: {
    barWidth,
    isLabelOpen,
    labelSize,
  },
} as any);

// TEST
interface ColorRampItem {
  id: number;
  label: string;
  value: string;
}

const colorRampSelect = ref(); // 用于获取下拉框dom
const colorRampList = ref<Array<ColorRampItem>>([
  {
    // echarts 默认色带
    id: 1,
    label: '明亮',
    value: 'echarts_light',
  },
  {
    id: 2,
    label: '渐变-红',
    value: 'gradual_ramp_red',
  },
  {
    id: 3,
    label: '渐变-绿',
    value: 'gradual_ramp_green',
  },
  {
    id: 4,
    label: '渐变-紫',
    value: 'gradual_ramp_purple',
  },
  {
    id: 5,
    label: '渐变-蓝',
    value: 'gradual_ramp_blue',
  },
  {
    id: 6,
    label: '渐变-橙',
    value: 'gradual_ramp_orange',
  },
]);

const getChartData = (feature: any) => {
  const keys = Object.keys(feature).filter((key) => key !== 'center');
  chartSeriesData.value = keys.map((key, index) => {
    const obj: barChartSeriesData = {
      name: key,
      type: 'bar',
      barWidth: barWidth.value,
      label: {
        show: isLabelOpen.value,
        position: 'top',
        fontSize: labelSize.value,
      },
      itemStyle: {
        color: colorsList.value[index],
      } as { color: any },
    };
    if (index === keys.length - 1) {
      obj.barGap = '0%';
    }
    return obj;
  });
  chartData.value = ['value']; // 恢复初始值
  keys.forEach((key) => {
    chartData.value.push(feature[key]);
  });
};
//  以第一个要素的相关字段值作为预览的数据
const getFieldData = async () => {
  const { selectedFields } = barChartRenderParams;

  const features = await vectorServiceApi.getCenterAndAttrByFields(
    currentLayer.value['source-layer'],
    selectedFields,
  );
  feature.value = features[0];
  getChartData(feature.value);
};
const renderParamsReturn = () => {
  const { renderParams } = currentLayer.value;
  const {
    selectedFields,
    colorRamp: colorRampParam,
    background: { point, polygon },
    markerOptions,
    seriesOptions,
    barHeightParam,
  } = renderParams;

  // 还原选中字段对应的索引
  selectedFields.forEach((selectedField: string) => {
    const index = fieldList.value.findIndex(
      (field) => field.label === selectedField,
    );

    if (index !== -1) {
      // 因为索引是从1开始的，所以加1
      selectedFieldsIndex.value.push(index + 1);
    }
  });

  colorRamp.value = colorRampParam;
  const { type } = currentLayer.value;
  const { layout, paint } = type === 'circle' ? point : polygon;
  barChartRenderParams.background.layout = layout;
  if (type === 'circle') {
    backgroundColor.value = paint['circle-color'];
    opacity.value = paint['circle-opacity'] * 100;
    barChartRenderParams.background.point.paint['circle-radius'] =
      paint['circle-radius'];
  } else {
    backgroundColor.value = paint['fill-color'];
    opacity.value = paint['fill-opacity'] * 100;
    barChartRenderParams.background.polygon.paint['fill-outline-color'] =
      paint['fill-outline-color'];
  }
  chartWidth.value = markerOptions.chartWidth;
  chartHeight.value = markerOptions.chartHeight;
  isLabelOpen.value = seriesOptions.isLabelOpen;
  if (seriesOptions.isLabelOpen) labelSize.value = seriesOptions.labelSize;
  barWidth.value = seriesOptions.barWidth;
  barHeight.value = 100 - Number.parseInt(barHeightParam, 10) * 2;
  getFieldData();
};

const getSource = () => {
  sceneStore.currentSceneConfig.sources.forEach((item: any) => {
    if (item.sourceId === currentLayer.value.source) {
      currentSource.value = item;
    }
  });
};
// 请求当前图层字段值
const requestFields = async () => {
  try {
    const res = await vectorServiceApi.getNumericFields(
      currentLayer.value['source-layer'],
    );
    fieldList.value = res.map((item: string, index: number) => {
      return {
        key: index + 1,
        label: item,
      };
    });
  } catch (error: any) {
    // 处理错误
    ElMessage.error(error.message);
  }
};

const handleColorRampSelectChange = (val: any) => {
  // 如果当前已选择字段，改变色带选择将重新绘制图例
  // if (field.value) {
  //   // drawLegend(true)
  // }
  if (val === 'echarts_light') {
    chartSeriesData.value.forEach((series: barChartSeriesData) => {
      delete series.itemStyle;
    });
  } else {
    colorsList.value = chartRender.getColorRampArray(
      val,
      selectedFieldsIndex.value.length,
    );
    getChartData(feature.value);
  }
  let img = null;
  colorRampList.value.forEach((item: any) => {
    if (item.value === val) {
      img = getRampUrl(item.value);
    }
  });
  // console.log(img)
  colorRampSelect.value.$el.children[0].children[0].children[1].setAttribute(
    'style',
    `
        background: url(${img}) no-repeat;
				background-position: 10px center;
				background-size: 80px 20px;
				text-indent: 100px;
				`,
  );
};
const handlePreViewChange = (_val: boolean | number | string) => {
  // console.log(val);
};

const handleSizeChange = (_val: any) => {
  // console.log(val);
};

const handlePanelChange = (panelName: CollapseModelValue) => {
  if (panelName !== 'chartParams') {
    isPreView.value = false;
  }
};

const handleFieldsChange = (fields: TransferKey[]) => {
  if (fields.length === 0) {
    isPreView.value = false;
    return;
  }
  getFieldData();
};

// watch([isLabelOpen, labelSize], () => {
//   console.log(1);
//   getChartData(feature.value)
// })
//
watch(
  barChartRenderParams,
  () => {
    publicStore.setRenderOptions(barChartRenderParams);
  },
  {
    immediate: true,
    deep: true,
  },
);
watch(
  () => isDragging.value,
  (newVal) => {
    if (newVal) {
      isPreView.value = false;
    }
  },
);
onMounted(async () => {
  getSource();
  await requestFields(); // 请求字段

  if (currentLayer.value.renderType[1] === 'bar') renderParamsReturn();
  handleColorRampSelectChange(colorRamp.value); // 当前默认的色带
});
onBeforeUnmount(() => {
  isPreView.value = false;
});
</script>

<template>
  <div class="all">
    <ElRow class="itemRow" style="display: flex; align-items: center">
      <span class="label-style"> 字段选择： </span>
      <ElTooltip
        effect="dark"
        content="参与饼图的字段，限制为数值型"
        placement="right"
      >
        <ElIcon size="14px" class="icon-style">
          <ElInfoFilled />
        </ElIcon>
      </ElTooltip>
    </ElRow>
    <ElRow class="itemRow">
      <ElCol :span="24">
        <ElTransfer
          v-model="selectedFieldsIndex"
          target-order="push"
          style="display: inline-block; text-align: left"
          :titles="['图层字段', '已选字段']"
          :format="{
            noChecked: '${total}',
            hasChecked: '${checked}/${total}',
          }"
          :data="fieldList"
          @change="handleFieldsChange"
        />
      </ElCol>
    </ElRow>
    <ElRow class="itemRow">
      <ElCol :span="24">
        <ElCollapse v-model="activeNames" accordion @change="handlePanelChange">
          <ElPopover
            :width="200"
            placement="right-start"
            trigger="click"
            popper-style="padding: 5px 0 0 0;"
            :offset="20"
            :visible="isPreView"
          >
            <template #reference>
              <ElCollapseItem name="chartParams">
                <template #title>
                  <div style="display: flex; align-items: center">
                    <span>图表参数</span>&nbsp;
                    <span @click.stop="">
                      <ElTooltip
                        effect="dark"
                        :content="isPreView ? '关闭预览' : '开启预览'"
                        placement="right"
                      >
                        <ElSwitch
                          v-model="isPreView"
                          inline-prompt
                          :active-icon="ElView"
                          :inactive-icon="ElHide"
                          size="default"
                          @change="handlePreViewChange"
                          :disabled="
                            !activeNames.includes('chartParams') ||
                            selectedFieldsIndex.length === 0
                          "
                        />
                      </ElTooltip>
                    </span>
                  </div>
                </template>
                <ElRow class="itemRow">
                  <ElCol :span="4">
                    <span class="label-style"> 颜色： </span>
                  </ElCol>
                  <ElCol :span="20">
                    <ElSelect
                      ref="colorRampSelect"
                      @change="handleColorRampSelectChange"
                      v-model="colorRamp"
                      placeholder="请选择输入色带"
                      style="width: 100%"
                      size="small"
                    >
                      <ElOption
                        v-for="item in colorRampList"
                        :key="item.id"
                        :label="item.label"
                        :value="item.value"
                      >
                        <ElRow type="flex" :gutter="20" justify="center">
                          <ElCol :span="18">
                            <img
                              :src="getRampUrl(item.value)"
                              style="float: left; height: 30px"
                            />
                          </ElCol>
                          <ElCol :span="6">
                            <span>{{ item.label }}</span>
                          </ElCol>
                        </ElRow>
                      </ElOption>
                    </ElSelect>
                  </ElCol>
                </ElRow>
                <ElRow class="itemRow">
                  <ElCol :span="6" style="display: flex; align-items: center">
                    <span class="label-style"> 图表容器&nbsp; </span>
                    <ElTooltip
                      effect="dark"
                      content="地图不可见，过大会引起遮挡，图表悬浮效果失效"
                      placement="top"
                    >
                      <ElIcon size="14px" class="icon-style">
                        <ElInfoFilled />
                      </ElIcon>
                    </ElTooltip>
                    ：
                  </ElCol>
                  <ElCol :span="2">
                    <span class="label-style"> 宽度 </span>
                  </ElCol>
                  <ElCol :span="6" class="define-input-number">
                    <ElInputNumber
                      v-model="chartWidth"
                      :min="50"
                      :max="170"
                      :step="5"
                      controls-position="right"
                      @change="handleSizeChange"
                      size="small"
                    />
                    <div class="define-append">px</div>
                  </ElCol>
                  <ElCol :span="2" />
                  <ElCol :span="2">
                    <span class="label-style"> 高度 </span>
                  </ElCol>
                  <ElCol :span="6" class="define-input-number">
                    <ElInputNumber
                      v-model="chartHeight"
                      :min="50"
                      :max="170"
                      :step="5"
                      controls-position="right"
                      @change="handleSizeChange"
                      size="small"
                    />
                    <div class="define-append">px</div>
                  </ElCol>
                </ElRow>
                <ElRow class="itemRow">
                  <ElCol :span="6" style="display: flex; align-items: center">
                    <span class="label-style"> 柱体高度： </span>
                  </ElCol>
                  <ElCol :span="18">
                    <ElSlider
                      v-model.number="barHeight"
                      show-input
                      class="define-slider"
                      size="small"
                    />
                  </ElCol>
                </ElRow>
                <ElRow class="itemRow">
                  <ElCol :span="6" style="display: flex; align-items: center">
                    <span class="label-style"> 柱体宽度： </span>
                  </ElCol>
                  <ElCol :span="7" class="define-input-number">
                    <ElInputNumber
                      v-model="barWidth"
                      :min="5"
                      :max="30"
                      controls-position="right"
                      @change="getChartData(feature)"
                      size="small"
                    />
                    <div class="define-append">px</div>
                  </ElCol>
                </ElRow>
                <ElRow class="itemRow">
                  <ElCol :span="6">
                    <span class="label-style"> 字体标注： </span>
                  </ElCol>
                  <ElCol :span="8">
                    <ElRadioGroup
                      v-model="isLabelOpen"
                      @change="getChartData(feature)"
                      size="small"
                    >
                      <ElRadio :label="true">开启</ElRadio>
                      <ElRadio :label="false">关闭</ElRadio>
                    </ElRadioGroup>
                  </ElCol>
                  <template v-if="isLabelOpen">
                    <ElCol :span="2">
                      <span class="label-style"> 大小 </span>
                    </ElCol>
                    <ElCol :span="8" class="define-input-number">
                      <ElInputNumber
                        v-model="labelSize"
                        :min="1"
                        :max="20"
                        controls-position="right"
                        @change="getChartData(feature)"
                        size="small"
                      />
                      <div class="define-append">px</div>
                    </ElCol>
                  </template>
                </ElRow>
              </ElCollapseItem>
            </template>
            <template #default>
              <div class="preView-container">
                <div class="preView-header">
                  <ElTooltip effect="dark" content="关闭" placement="top">
                    <div class="close-btn-box" @click="isPreView = false">
                      <ElIcon class="close-btn">
                        <ElDArrowLeft />
                      </ElIcon>
                    </div>
                  </ElTooltip>
                  <span class="preView-title">预览</span>
                  <ElTooltip
                    effect="dark"
                    content="与地图显示1:1.5大小的图表预览"
                    placement="top"
                  >
                    <ElIcon class="detail-btn" size="15">
                      <svg aria-hidden="true">
                        <use xlink:href="#icon-bangzhu" />
                      </svg>
                    </ElIcon>
                  </ElTooltip>
                </div>
                <div class="preView-body">
                  <div
                    class="chart-container"
                    :style="{
                      width: `${chartWidth}px`,
                      height: `${chartHeight}px`,
                    }"
                  >
                    <BarChart :options="chartOptions" v-if="isPreView" />
                  </div>
                </div>
              </div>
            </template>
          </ElPopover>
          <ElCollapseItem title=" 背景参数" name="backgroundParams">
            <ElRow class="itemRow">
              <ElCol :span="4">
                <span class="label-style"> 颜色： </span>
              </ElCol>
              <ElCol :span="20">
                <ElInput
                  class="colorInput"
                  v-model="backgroundColor"
                  type="color"
                  size="small"
                />
              </ElCol>
            </ElRow>
            <ElRow class="itemRow">
              <ElCol :span="6">
                <span class="label-style"> 不透明度： </span>
              </ElCol>
              <ElCol :span="18">
                <ElSlider v-model.number="opacity" show-input size="small" />
              </ElCol>
            </ElRow>
            <ElRow class="itemRow" v-if="currentLayer.type === 'circle'">
              <ElCol :span="4">
                <span class="label-style"> 大小： </span>
              </ElCol>
              <ElCol :span="20">
                <ElInput
                  v-model.number="
                    barChartRenderParams.background.point.paint['circle-radius']
                  "
                  placeholder="Please input"
                  size="small"
                >
                  <template #append>像素</template>
                </ElInput>
              </ElCol>
            </ElRow>
            <ElRow class="itemRow" v-else>
              <ElCol :span="4">
                <span class="label-style"> 外轮廓线： </span>
              </ElCol>
              <ElCol :span="20">
                <ElInput
                  class="colorInput"
                  v-model="
                    barChartRenderParams.background.polygon.paint[
                      'fill-outline-color'
                    ]
                  "
                  type="color"
                  size="small"
                />
              </ElCol>
            </ElRow>
          </ElCollapseItem>
        </ElCollapse>
      </ElCol>
    </ElRow>
  </div>
</template>
<style lang="scss" scoped>
/* 修改浏览器默认滚动条样式(el-transfer滚动条被污染成默认滚动条) */

:deep(::-webkit-scrollbar) {
  width: 7px;
}

:deep(::-webkit-scrollbar-thumb) {
  background-color: #c0c4cc;
  border-radius: 5px;
}

:deep(::-webkit-scrollbar-thumb:hover) {
  cursor: pointer;
  background-color: #a5a9b5;
}

:deep(::-webkit-scrollbar-track) {
  background-color: #f4f4f4;
}

.all {
  width: 100%;
}

.itemRow {
  width: 100%;
  padding: 5px;
}

.el-input {
  width: 100%;
}

.label-style {
  font-size: 15px;
}

.colorInput {
  caret-color: transparent;
}

:deep(.colorInput .el-input__inner:hover) {
  cursor: pointer;
}

:deep(.el-table .el-table__cell) {
  text-align: center;
}

.preView {
  height: 170px;
}

.legend {
  margin-top: 2px;
}

:deep(.el-table:not(.el-table--border) .el-table__cell) {
  border: none;

  /* 去除表格边框 */
}

:deep(.el-table--small .cell) {
  height: 25px;
  padding-right: 20px;
}

/* 修改el-transfer大小 */
:deep(.el-transfer-panel) {
  width: 220px;
  height: 185px;
}

:deep(.el-transfer) {
  --el-transfer-panel-header-height: 25px;
}

:deep(
  .el-transfer-panel .el-transfer-panel__header .el-checkbox .el-checkbox__label
) {
  font-size: 13px;
}

:deep(.el-transfer-panel__body) {
  --el-transfer-panel-body-height: 158px;

  /* height: 150px; */
}

:deep(.el-transfer__buttons) {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
}

:deep(.el-transfer__button:nth-child(2)) {
  margin: 5px 0 0;
}

/* :deep(.el-transfer-panel__list.is-filterable) {
  height: 10px;
} */

:deep(.el-collapse-item__header) {
  font-size: 15px;
  font-weight: 600;
}

.icon-style:hover {
  color: rgb(63 158 255);
  cursor: pointer;
}

.preView-container {
  width: 200px;
  height: 200px;

  .preView-header {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 25px;
  }

  .preView-header .preView-title {
    font-size: 14px;
    font-weight: 700;
  }

  .preView-header .close-btn-box {
    position: absolute;
    top: 0;
    left: 5px;
    box-sizing: border-box;
    width: 25px;
    height: 100%;

    /* margin-left: 10px; */

    &:hover {
      font-weight: 700;

      /* transform: scale(1.05); */
      color: rgb(63 158 255);
      cursor: pointer;
      border: 1px solid rgb(63 158 255);
    }
  }

  .preView-header .close-btn {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }

  .preView-header .detail-btn {
    /* box-sizing: border-box; */
    position: absolute;
    top: 0;
    right: 5px;
    width: 25px;
    height: 100%;

    &:hover {
      font-weight: 700;
      color: rgb(63 158 255);
      cursor: pointer;
    }
  }

  .preView-body {
    /* 让图表始终居中 */
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: calc(100% - 25px);
  }

  .preView-body .chart-container {
    /* 这种绑定变量方式初始化值在子组件内获取不到，原因？ */

    /* width: v-bind(chartWidth);
    height: v-bind(chartHeight); */

    /* max-width: 100%;
    max-height: calc(100% - 25px); */

    /* width: 100%;
    height: calc(100% - 25px); */

    border: 1px solid rgb(63 158 255);
    border-radius: 5px;
  }
}

/* 自定义数字输入框append  */
.define-input-number {
  display: flex;
  width: 100%;
  border: 1px solid #dcdfe6;
  border-radius: 8px;

  .el-input-number--mini {
    flex: 1;
  }

  :deep(.el-input__inner) {
    border: none !important;
  }
}

.define-append {
  display: inline-block;
  width: 40px;
  padding: 0 3px;
  font-size: 12px;

  /* height: 32px;
  line-height: 32px; */
  color: #909399;
  text-align: center;
  background: #f5f7fa;
  border-left: none;
}

/* 自定义slider后置数字输入框内单位  */
:deep(.define-slider .el-input-number) {
  position: relative;

  :deep(&::after) {
    position: absolute;
    top: 50%;
    right: 32px;
    display: inline-block;
    width: 20px;
    height: 20px;
    line-height: 20px;
    text-align: center;
    content: '%';
    transform: translateY(-50%);
  }
}

:deep(.el-transfer-panel__item.el-checkbox) {
  color: #606266;

  .el-checkbox__label {
    font-size: 12px;
    font-weight: normal;
  }
}
</style>
